package com.dingreading.cloud.soms.controller;

import com.alibaba.fastjson.JSONObject;
import com.dingreading.cloud.common.base.R;
import com.dingreading.cloud.common.dto.LoginDataDto;
import com.dingreading.cloud.common.util.*;
import com.dingreading.cloud.common.util.excel.ExcelHandler;
import com.dingreading.cloud.common.util.excel.RowBean;
import com.dingreading.cloud.soms.dto.SignInVO;
import com.dingreading.cloud.soms.dto.StoreSignInDto;
import com.dingreading.cloud.soms.entity.StoreSignIn;
import com.dingreading.cloud.soms.service.StoreSignInService;
import com.dingreading.cloud.soms.util.LoginInfoUtil;
import com.google.common.collect.Lists;
import com.mybatisflex.core.paginate.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.util.CellRangeAddress;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/front/storeSignIn")
@Api(tags = "门店-签到记录管理")
public class FrontStoreSignInController {

    @Resource
    private StoreSignInService storeSignInService;

    @ApiOperation(value = "分页列表")
    @PostMapping(value = "/v2/pageList")
    public R<Object> pageListV2(
            HttpServletRequest request,
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "分页公共类") PageUtil pageUtil,
            @ApiParam(value = "会员姓名") @RequestParam(value = "memberName", required = false) String memberName,
            @ApiParam(value = "到店状态记录：1.到店 2.离店") @RequestParam(value = "status", required = false) Integer status,
            @ApiParam(value = "开始日期") @RequestParam(value = "beginDate", required = false) String beginDate,
            @ApiParam(value = "结束日期") @RequestParam(value = "endDate", required = false) String endDate,
            @ApiParam(value = "是否好读会员 1.是 0.否") @RequestParam(value = "readStatus", required = false) Integer readStatus
    ) {
        // 获取员工信息
        R<Object> r = LoginInfoUtil.getLoginDto(request);
        if (R.isError(r)) return r;
        LoginDataDto loginDto = (LoginDataDto) r.getData();
        long storeId = loginDto.getCurrentStoreId();

        Page<StoreSignInDto> page = this.storeSignInService.pageList(pageUtil, storeId, storeUid, memberName, status, beginDate, endDate, readStatus);

        List<StoreSignInDto> list = page.getRecords();
        if (CollectionUtils.isNotEmpty(list)) {
            List<String> memberUids = list.stream().map(StoreSignInDto::getMemberUid).collect(Collectors.toList());

            // 获取会员的出勤次数
            Map<String, Integer> signInNum = new HashMap<>();
            if (StringUtils.isNotBlank(beginDate) && StringUtils.isNotBlank(endDate)) {
                signInNum = storeSignInService.getMemberSignInNum(storeId, memberUids, beginDate, endDate);
            }

            // 获取会员的出勤总次数
            Map<String, Integer> signInCnt = storeSignInService.getMemberSignInCnt(memberUids);

            for (StoreSignInDto dto : list) {
                String memberUid = dto.getMemberUid();
                // 出勤次数
                if (signInNum != null && signInNum.size() > 0)
                    dto.setSignInNum(signInNum.get(memberUid));

                // 出勤总次数
                if (signInCnt != null && signInCnt.size() > 0)
                    dto.setSignInCnt(signInCnt.get(memberUid));
            }

        }
        PageBeanDto dto = new PageBeanDto();
        dto.setTotal(page.getTotalRow());
        dto.setList(list);
        return R.ok(dto);
    }

    @ApiOperation(value = "当天的会员到店记录")
    @PostMapping(value = "/todayList")
    public R<Object> todayList(
            HttpServletRequest request,
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "会员姓名") @RequestParam(value = "memberName", required = false) String memberName,
            @ApiParam(value = "到店状态记录：1.到店 2.离店") @RequestParam(value = "status", required = false) Integer status,
            @ApiParam(value = "查询日期 yyyy-MM-dd") @RequestParam(value = "date", required = false) String date
    ) {
        // 获取员工信息
        R<Object> r = LoginInfoUtil.getLoginDto(request);
        if (R.isError(r)) return r;
        LoginDataDto loginDto = (LoginDataDto) r.getData();

        long storeId = loginDto.getCurrentStoreId();
//        long storeId=2l;
        // 默认查当天日期
        if (StringUtils.isBlank(date))
            date = DateUtil.getNowDateStr();

        JSONObject list = this.storeSignInService.todayList(storeId, memberName, status, date);
        return R.ok(list);
    }

    @ApiOperation(value = "导出会员到店记录")
    @PostMapping(value = "/exportList", produces = "application/vnd.ms-excel;charset=UTF-8")
    public void exportList(
            HttpServletRequest request,
            HttpServletResponse response,
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "会员姓名") @RequestParam(value = "memberName", required = false) String memberName,
            @ApiParam(value = "到店状态记录：1.到店 2.离店") @RequestParam(value = "status", required = false) Integer status,
            @ApiParam(value = "开始日期") @RequestParam(value = "beginDate", required = false) String beginDate,
            @ApiParam(value = "结束日期") @RequestParam(value = "endDate", required = false) String endDate,
            @ApiParam(value = "是否好读会员 1.是 0.否") @RequestParam(value = "readStatus", required = false) Integer readStatus
    ) throws Exception {
        // 获取员工信息
        R<Object> r = LoginInfoUtil.getLoginDto(request);
        if (R.isError(r)) throw new DescribeException(r.getMsg());
        LoginDataDto loginDto = (LoginDataDto) r.getData();

        long storeId = loginDto.getCurrentStoreId();

        //  获取本月的第一天和最后一天
        if (StringUtils.isBlank(beginDate) || StringUtils.isBlank(endDate)) {
            Date monthMinDate = DateUtil.getMonthMinDate();
            Date monthMaxDate = DateUtil.getMonthMaxDate();
            beginDate = DateUtil.getDefaultTime2DateStr(monthMinDate);
            endDate = DateUtil.getDefaultTime2DateStr(monthMaxDate);
        }

        List<StoreSignIn> list = storeSignInService.getStoreSignInList(storeId, storeUid, memberName, status, beginDate, endDate, readStatus);
        if (CollectionUtils.isEmpty(list))
            throw new DescribeException("没有查询到数据");

        // 按会员进行分组
        Map<String, List<StoreSignIn>> map = list.stream().collect(Collectors.groupingBy(StoreSignIn::getMemberUid, LinkedHashMap::new, Collectors.toList()));
        ArrayList<String> memberUids = Lists.newArrayList(map.keySet());
        // 获取会员的出勤总次数
        Map<String, Integer> signInCntMap = storeSignInService.getMemberSignInCnt(memberUids);
        // 获取会员的出勤次数
        Map<String, Integer> signInNumMap = storeSignInService.getMemberSignInNum(storeId, memberUids, beginDate, endDate);

        // 需要合并的行号
        List<RowBean> firstRows = new ArrayList<>();
        // 需要合并的列号
        List<Integer> firstColumns = Lists.newArrayList(0);
        int secondStartRow = 1;
        int secondEndRow = 0;
        // 需要合并的行号
        List<RowBean> secondRows = new ArrayList<>();
        // 需要合并的列号
        List<Integer> secondColumns = Lists.newArrayList(1, 2, 3);
        firstRows.add(new RowBean(1, list.size()));

        // 会员数量
        int memberNum = map.size();
        // 导出数据集合
        List<SignInVO> voList = new ArrayList<>();

        for (Map.Entry<String, Integer> entry : signInNumMap.entrySet()) {
            String memberUid = entry.getKey();
            List<StoreSignIn> signInList = map.get(memberUid);

            int signInNum = signInList.size();

            Integer signNum = signInNumMap.get(memberUid);
            Integer signCnt = signInCntMap.get(memberUid);

            secondEndRow += signInNum;
            // 合并必须包含2个或更多单元格
            if (secondStartRow != secondEndRow)
                secondRows.add(new RowBean(secondStartRow, secondEndRow));
            secondStartRow += signInNum;

            for (StoreSignIn data : signInList) {
                SignInVO vo = new SignInVO();
                vo.setMemberNum(memberNum);
                vo.setMemberName(data.getMemberName());
                vo.setStoreInNum(signNum);
                vo.setSignInCnt(signCnt);
                vo.setStoreName(data.getStoreName());
                // 到店状态记录：1.到店 2.离店
                vo.setStatus(data.getStatus().equals(1) ? "到店" : "离店");
                if (null != data.getDuration()) {
                    String time = TimeUtil.convertSecondsToHMS(data.getDuration());
                    vo.setDuration(time);
                }
                if (null != data.getArrivalTime())
                    vo.setArrivalTime(DateUtil.getDefaultTimeStr(data.getArrivalTime()));
                if (null != data.getLeaveTime())
                    vo.setLeaveTime(DateUtil.getDefaultTimeStr(data.getLeaveTime()));
                vo.setAddTime(DateUtil.getDefaultTimeStr(data.getAddTime()));

                voList.add(vo);
            }
        }

        List<CellRangeAddress> cellRangeAddressList = new ArrayList<>();
        for (RowBean row : firstRows) {
            for (Integer column : firstColumns) {
                cellRangeAddressList.add(new CellRangeAddress(row.getBeginRow(), row.getEndRow(), column, column));
            }
        }
        for (RowBean row : secondRows) {
            for (Integer column : secondColumns) {
                cellRangeAddressList.add(new CellRangeAddress(row.getBeginRow(), row.getEndRow(), column, column));
            }
        }

        String fileName = "签到记录" + beginDate + "至" + endDate;
        ExcelHandler.exportMergeExcel2(response, voList, SignInVO.class, fileName, "签到记录", cellRangeAddressList);
    }

}
